package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.globalvariable.WechatSubscriptionGlobalVariable;
import cn.com.acca.ma.service.BoardIndexService;
import cn.com.acca.ma.service.ModelMACDGoldCrossService;
import cn.com.acca.ma.service.ModelStockAnalysisService;
import cn.com.acca.ma.service.ModelSubNewStockService;
import cn.com.acca.ma.service.ModelTopStockService;
import cn.com.acca.ma.service.StockIndexService;
import cn.com.acca.ma.service.StockIndexWeekService;
import cn.com.acca.ma.service.StockTransactionDataAllService;
import cn.com.acca.ma.service.StockTransactionDataService;
import cn.com.acca.ma.service.StockWeekService;
import cn.com.acca.ma.service.WechatSubscriptionService;
import cn.com.acca.ma.thread.picture.CreateAllBoardIndexClosePictureThread;
import cn.com.acca.ma.thread.picture.CreateAllBoardIndexFiveAndTenDayRatePictureThread;
import cn.com.acca.ma.thread.picture.CreateBoardPictureThread;
import cn.com.acca.ma.thread.picture.CreateClosePictureThread;
import cn.com.acca.ma.thread.picture.CreateDifferentiationPictureThread;
import cn.com.acca.ma.thread.picture.CreateMACDGoldCrossScatterPlotPictureThread;
import cn.com.acca.ma.thread.picture.CreateMACDGoldCrossStockRatePictureThread;
import cn.com.acca.ma.thread.picture.CreateMACDPictureThread;
import cn.com.acca.ma.thread.picture.CreateMACDSuccessRatePictureThread;
import cn.com.acca.ma.thread.picture.CreateMovingAverageBullRankShortOrderPictureThread;
import cn.com.acca.ma.thread.picture.CreateSpiderWebPlotPictureThread;
import cn.com.acca.ma.thread.picture.CreateStockBigBoardUpDownPercentagePictureThread;
import cn.com.acca.ma.thread.picture.CreateStockIndexHeiKinAshiPictureThread;
import cn.com.acca.ma.thread.picture.CreateStockLimitUpAndDownPictureThread;
import cn.com.acca.ma.thread.picture.CreateSubNewStockAverageClosePictureThread;
import cn.com.acca.ma.thread.picture.CreateTopStockUpDownPictureThread;
import cn.com.acca.ma.thread.write.WriteBoardIndexFiveAndTenDayRateByDateThread;
import cn.com.acca.ma.thread.write.WriteBoardIndexByDateThread;
import cn.com.acca.ma.thread.write.WriteBoardIndexUpDownPercentageByDateThread;
import cn.com.acca.ma.thread.write.WriteBoardIndexUpDownRankByDateThread;
import cn.com.acca.ma.thread.write.WriteKDByDateThread;
import cn.com.acca.ma.thread.write.WriteMACDByDateThread;
import cn.com.acca.ma.thread.write.WriteModelMACDGoldCrossIncrThread;
import cn.com.acca.ma.thread.write.WriteModelStockAnalysisByDateThreading;
import cn.com.acca.ma.thread.write.WriteModelTopStockThread;
import cn.com.acca.ma.thread.write.WriteMovingAverageByDateThread;
import cn.com.acca.ma.thread.write.WriteStockIndexBiasByDateThread;
import cn.com.acca.ma.thread.write.WriteStockIndexByDateThread;
import cn.com.acca.ma.thread.write.WriteStockIndexHeiKinAshiByDateThread;
import cn.com.acca.ma.thread.write.WriteStockIndexMAByDateThread;
import cn.com.acca.ma.thread.write.WriteStockTransactionDataAllByDateThread;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

public class WechatSubscriptionServiceImpl extends BaseServiceImpl<WechatSubscriptionServiceImpl, Object> implements
    WechatSubscriptionService {

    private static Logger logger = LogManager.getLogger(WechatSubscriptionServiceImpl.class);

    private static ExecutorService executorService;

    private final long awaitTime = 5 * 1000;

    /**
     * 并行执行基于基本数据的工作，具体如下：
     * 1.writeMovingAverageByDate
     * 2.createClosePicture
     * 3.createStockLimitUpAndDownPicture
     * 4.createStockBigBoardUpDownPercentagePicture
     * 5.createTopStockUpDownPicture
     * 6.createSubNewStockAvgClosePicture
     */
    @Override
    public void asyncHandleBasedOnBasicData() {
        logger.info("=====================并行执行基于基本数据的工作=====================");

        Integer threadNumber = 5;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        StockTransactionDataService stockTransactionDataService = new StockTransactionDataServiceImpl();
        executorService.execute(new WriteMovingAverageByDateThread(stockTransactionDataService));
        executorService.execute(new CreateClosePictureThread(stockTransactionDataService));
        executorService.execute(new CreateStockLimitUpAndDownPictureThread(stockTransactionDataService));
        executorService.execute(new CreateStockBigBoardUpDownPercentagePictureThread(stockTransactionDataService));
        ModelTopStockService modelTopStockService = new ModelTopStockServiceImpl();
        executorService.execute(new CreateTopStockUpDownPictureThread(modelTopStockService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================并行执行基于基本数据的工作完成=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 并行执行基于移动平均线的工作，具体如下：
     * 1.writeMACDByDate
     * 2.writeModelMACDGoldCrossIncr();
     * 3.createMovingAverageBullRankShortOrderPicture
     */
    @Override
    public void asyncHandleBasedOnMovingAverage() {
        logger.info("=====================并行执行基于移动平均线的工作=====================");

        Integer threadNumber = 3;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        StockTransactionDataService stockTransactionDataService = new StockTransactionDataServiceImpl();
        executorService.execute(new WriteMACDByDateThread(stockTransactionDataService));
        ModelMACDGoldCrossService modelMACDGoldCrossService = new ModelMACDGoldCrossServiceImpl();
        executorService.execute(new WriteModelMACDGoldCrossIncrThread(modelMACDGoldCrossService));
        executorService.execute(new CreateMovingAverageBullRankShortOrderPictureThread(stockTransactionDataService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================并行执行基于移动平均线的工作完成=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 并行执行基于MACD的工作，具体如下：
     * 1.writeStockIndexByDate();
     * 2.writeStockIndexMAByDate();
     * 3.writeStockIndexBiasByDate();
     * 4.writeStockIndexHeiKinAshiByDate();
     * 5.createMACDPicture
     * 6.createMACDGoldCrossStockRatePicture
     * 7.createMACDGoldCrossScatterPlotPicture
     * 8.createMACDSuccessRatePicture
     */
    @Override
    public void asyncHandleBasedOnMACD() {
        logger.info("=====================并行执行基于MACD的工作=====================");

        Integer threadNumber = 8;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        StockIndexService stockIndexService = new StockIndexServiceImpl();
        executorService.execute(new WriteStockIndexByDateThread(stockIndexService));
        executorService.execute(new WriteStockIndexMAByDateThread(stockIndexService));
        executorService.execute(new WriteStockIndexBiasByDateThread(stockIndexService));
        executorService.execute(new WriteStockIndexHeiKinAshiByDateThread(stockIndexService));
        StockTransactionDataService stockTransactionDataService = new StockTransactionDataServiceImpl();
        executorService.execute(new CreateMACDPictureThread(stockTransactionDataService));
        executorService.execute(new CreateMACDGoldCrossStockRatePictureThread(stockTransactionDataService));
        ModelMACDGoldCrossService modelMACDGoldCrossService = new ModelMACDGoldCrossServiceImpl();
        executorService.execute(new CreateMACDGoldCrossScatterPlotPictureThread(modelMACDGoldCrossService));
        executorService.execute(new CreateMACDSuccessRatePictureThread(modelMACDGoldCrossService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================并行执行基于MACD的工作完成=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 并行执行基于STOCK_INDEX表的工作，具体如下：
     * 1.createStockIndexHeiKinAshiPicture
     * 2.createDifferentiationPicture
     */
    @Override
    public void asyncHandleBasedOnStockIndex() {
        logger.info("=====================并行执行基于STOCK_INDEX表的工作=====================");

        Integer threadNumber = 2;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        StockIndexService stockIndexService = new StockIndexServiceImpl();
        executorService.execute(new CreateStockIndexHeiKinAshiPictureThread(stockIndexService));
        StockTransactionDataService stockTransactionDataService = new StockTransactionDataServiceImpl();
        executorService.execute(new CreateDifferentiationPictureThread(stockTransactionDataService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================并行执行基于STOCK_INDEX表的工作完成=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 并行执行基于BOARD_INDEX表的工作，具体如下：
     * 1.writeBoardIndexByDate();
     * 2.writeBoardIndexFiveAndTenDayRateByDate();
     * 3.writeBoardIndexUpDownPercentageByDate();
     * 4.writeBoardIndexUpDownRankByDate();
     * 5.createSpiderWebPlotPicture
     * 6.createBoardPicture
     * 7.createAllBoardIndexClosePicture
     * 8.createAllBoardIndexFiveAndTenDayRatePicture
     */
    @Override
    public void asyncHandleBasedOnBoardIndex() {
        logger.info("=====================并行执行基于BOARD_INDEX表的工作=====================");

        Integer threadNumber = 8;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        BoardIndexService boardIndexService = new BoardIndexServiceImpl();
        executorService.execute(new WriteBoardIndexByDateThread(boardIndexService));
        executorService.execute(new WriteBoardIndexFiveAndTenDayRateByDateThread(boardIndexService));
        executorService.execute(new WriteBoardIndexUpDownPercentageByDateThread(boardIndexService));
        executorService.execute(new WriteBoardIndexUpDownRankByDateThread(boardIndexService));
        executorService.execute(new CreateSpiderWebPlotPictureThread(boardIndexService));
        executorService.execute(new CreateBoardPictureThread(boardIndexService));
        executorService.execute(new CreateAllBoardIndexClosePictureThread(boardIndexService));
        executorService.execute(new CreateAllBoardIndexFiveAndTenDayRatePictureThread(boardIndexService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================并行执行基于STOCK_INDEX表的工作完成=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 基于周线级别数据的穿行处理：计算数据，生成图片。内容如下：
     * writeStockWeekByDate();
     * writeStockWeekKDByDate();
     * writeStockWeekUpDownByDate();
     * writeStockWeekMACDByDate();
     * writeStockIndexWeekByDate();
     * writeStockIndexWeekHeiKinAshiByDate();
     * createWeekKDPicture();
     * createStockIndexWeekHeiKinAshiPicture();
     */
    public void handleBasedOnWeekData() {
        logger.info("=====================基于周线级别数据的穿行处理：计算数据，生成图片=====================");

        StockWeekService stockWeekService = new StockWeekServiceImpl();
        stockWeekService.writeStockWeekByDate();
        stockWeekService.writeStockWeekKDByDate();
        stockWeekService.writeStockWeekUpDownByDate();
        stockWeekService.writeStockWeekMACDByDate();

        stockWeekService.createWeekKDPicture(Boolean.TRUE);

        StockIndexWeekService stockIndexWeekService = new StockIndexWeekServiceImpl();
        stockIndexWeekService.writeStockIndexWeekByDate();
        stockIndexWeekService.writeStockIndexWeekHeiKinAshiByDate();

        stockIndexWeekService.createStockIndexWeekHeiKinAshiPicture(Boolean.TRUE);

        logger.info("=====================基于周线级别数据的穿行处理：计算数据，生成图片，工作完成=====================");
    }

    /**
     * 创建word格式的报告。内容如下：
     *
     * 股票样本总数
     * 股票上涨家数
     * 股票持平的家数
     * 股票下跌的家数
     *
     * 日线级别反转股票
     * 日线级别MACD金叉的股票信息
     * 某一周MACD底背离的股票信息
     * 某一周KD指标金叉时的股票信息
     * 日线级别MACD最低的股票
     * 某一周KD指标最低的股票的股票
     * 日线级别异常股票的信息
     *
     * 写入多头排列的股票的数量，股票名称/股票代码
     * 写入空头排列的股票的数量，股票名称/股票代码
     *
     * 28分化图
     * 多空排列图（最近10年的图和半年的图）
     * 收盘价图STOCK_CLOSE
     * 日线级别MACD图
     * 日线级别蜘蛛雷达图
     * 周线级别KD指标图
     * 日线级别各个板块的K线图
     * 日线级别板块收盘价图（最近10年的图和半年的图）
     * 日线级别板块5日和10涨跌图（最近10年的图和半年的图）
     * 日线级别股票涨停跌停数量图
     *
     * 日线级别股票收盘价到达250日均线支撑的股票
     * 日线级别股票收盘价到达120日均线支撑的股票
     *
     * 日线级别某一段时间内上涨股票的前number名
     * 日线级别某一段时间内下跌股票的前number名
     */
    @Override
    public void generateWechatSubscriptionReport() {

    }

    /**
     * 生成完微信订阅号报告后，计算基础数据，具体如下：
     * 1.writeKDByDate
     * 2.writeStockTransactionDataAllByDate
     * 3.writeModelTopStock();
     * 4.writeModelStockAnalysisByDate();
     */
    @Override
    public void calculateBasicDataAfterGeneratingWechatSubscriptionReport() {
        logger.info("=====================生成完微信订阅号报告后，计算基础数据=====================");

        Integer threadNumber = 5;
        this.executorService = Executors.newFixedThreadPool(threadNumber);

        WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber = 0;

        StockTransactionDataService stockTransactionDataService = new StockTransactionDataServiceImpl();
        executorService.execute(new WriteKDByDateThread(stockTransactionDataService));
        StockTransactionDataAllService stockTransactionDataAllService = new StockTransactionDataAllServiceImpl();
        executorService.execute(new WriteStockTransactionDataAllByDateThread(stockTransactionDataAllService));
        ModelTopStockService modelTopStockService = new ModelTopStockServiceImpl();
        executorService.execute(new WriteModelTopStockThread(modelTopStockService));
        ModelStockAnalysisService modelStockAnalysisService = new ModelStockAnalysisServiceImpl();
        executorService.execute(new WriteModelStockAnalysisByDateThreading(
            modelStockAnalysisService));
        ModelSubNewStockService modelSubNewStockService = new ModelSubNewStockServiceImpl();
        executorService.execute(new CreateSubNewStockAverageClosePictureThread(modelSubNewStockService));

        // 每个一段时间（threadIntervalSleepStockTransactionDataCalculateBasicDataFinish）就检查一遍股票交易移动平均线和MACD是否计算完成
        int threadIntervalSleepStockTransactionDataCalculateBasicDataFinish = Integer.valueOf(
            PropertiesUtil.getValue(THREAD_PROPERTIES,
                "thread.interval.sleep.stockTransactionData.calculateBasicData.finish"));
        while (true) {
            if (threadNumber.equals(WechatSubscriptionGlobalVariable.wechatSubscriptionThreadFinishNumber)) {
                logger.info("=====================生成完微信订阅号报告后，计算基础数据=====================");

                // 关闭线程池
                this.closeThreadPool();

                break;
            } else {
                try {
                    Thread.sleep(threadIntervalSleepStockTransactionDataCalculateBasicDataFinish);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 关闭线程池
     */
    private void closeThreadPool(){
        // 关闭线程池
        try {
            // 向学生传达“问题解答完毕后请举手示意！”
            this.executorService.shutdown();

            // 向学生传达“XX分之内解答不完的问题全部带回去作为课后作业！”后老师等待学生答题
            // (所有的任务都结束的时候，返回TRUE)
            if(!this.executorService.awaitTermination(awaitTime, TimeUnit.MILLISECONDS)){
                // 超时的时候向线程池中所有的线程发出中断(interrupted)。
                this.executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            // awaitTermination方法被中断的时候也中止线程池中全部的线程的执行。
            e.printStackTrace();

            this.executorService.shutdownNow();
        }
    }

    @Override
    public String listToString(List list) {
        return null;
    }


}
